﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Repository.Hierarchy;
using MapReduceLib.Configuration;
using System.Xml.Serialization;
using System.IO;
using MapReduceLib.Contracts;
using System.ServiceModel;
using MasterNode.ServiceImpl;
using Ninject;
using MapReduceLib;

namespace MasterNode
{
    class Program
    {
        private static ILog Log = LogManager.GetLogger(typeof(Program));
        private static ClusterConfig configuration;

        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();
            Log.Debug("Starting master node, reading configuration file...");
            configuration = ReadClusterConfiguration();

            Log.DebugFormat("Cluster name: {0}", configuration.ClusterName);
            Log.DebugFormat("Starting up WCF services...");             

            // DI Container bootup...
            IKernel kernel = new StandardKernel(new ServerModule());

            NetTcpBinding binding = WCFUtils.GetDefaultBinding();

            ServiceHost serviceHostJobManager = new ServiceHost(kernel.Get<IJobManager>());
            Log.DebugFormat("Publishing JobManager service at URL net.tcp://localhost:{0}/JobManager/", configuration.MasterPort);
            serviceHostJobManager.AddServiceEndpoint(typeof(IJobManager), binding, string.Format("net.tcp://localhost:{0}/JobManager/", configuration.MasterPort));
            serviceHostJobManager.Open();

            Log.DebugFormat("Publishing TaskTracker service at URL net.tcp://localhost:{0}/TaskTracker/", configuration.MasterPort);
            ServiceHost serviceHostTaskTracker = new ServiceHost(kernel.Get<ITaskTracker>());
            serviceHostTaskTracker.AddServiceEndpoint(typeof(ITaskTracker), binding, string.Format("net.tcp://localhost:{0}/TaskTracker/", configuration.MasterPort));
            serviceHostTaskTracker.Open();

            Cluster cluster = new Cluster(configuration);

            Log.Debug("Master node initialization complete...");
            Console.ReadLine();
        }

        private static ClusterConfig ReadClusterConfiguration()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ClusterConfig));

            using (FileStream fs = new FileStream("./ClusterConfig.xml", FileMode.Open, FileAccess.Read))
            {
                return xmlSerializer.Deserialize(fs) as ClusterConfig;
            }
        }
    }
}
